package com.elai.tags.controller;

import java.util.*;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.elai.baseconfig.domain.EventItemDO;
import com.elai.baseconfig.domain.EventTypeDO;
import com.elai.baseconfig.service.EventItemService;
import com.elai.baseconfig.service.EventTypeService;
import com.elai.common.annotation.Log;
import com.elai.common.constant.HttpStatus;
import com.elai.common.constant.ThirdInterface;
import com.elai.common.core.controller.BaseController;
import com.elai.common.core.domain.AjaxResult;
import com.elai.common.core.domain.entity.SysUser;
import com.elai.common.core.page.PageDomain;
import com.elai.common.core.page.TableDataInfo;
import com.elai.common.core.page.TableSupport;
import com.elai.common.core.text.Convert;
import com.elai.common.enums.BusinessType;
import com.elai.common.utils.*;
import com.elai.common.utils.sql.SqlTableUtil;
import com.elai.tags.domain.BaseGroupExtractHistoryDO;
import com.elai.tags.domain.BaseUserGroupTaskDetail;
import com.elai.tags.domain.UserDetailVo;
import com.elai.tags.domain.vo.UserTrackGroupVO;
import com.elai.tags.domain.vo.UserTrackVO;
import com.elai.tags.service.IBaseUserGroupTaskDetailService;
import com.github.pagehelper.PageInfo;
import org.apache.http.HttpException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.elai.tags.domain.BaseUserGroupDO;
import com.elai.tags.service.BaseUserGroupService;
import com.elai.common.utils.poi.ExcelUtil;

/**
 * 用户分群Controller
 *
 * @author elai
 * @date 2021-06-19
 */
@RestController
@RequestMapping("/base/group")
public class BaseUserGroupController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(BaseUserGroupController.class);
    @Autowired
    private BaseUserGroupService baseUserGroupService;

    @Autowired
    private ThirdProperties thirdProperties;

    @Autowired
    private EventTypeService eventTypeService;

    @Autowired
    private EventItemService eventItemService;

    @Autowired
    private IBaseUserGroupTaskDetailService baseUserGroupTaskDetailService;



    /**
     * 查询用户分群列表
     */
    @PreAuthorize("@ss.hasPermi('base:group:list')")
    @GetMapping("/list")
    public TableDataInfo list(BaseUserGroupDO baseUserGroup)
    {
        startPage();
        List<BaseUserGroupDO> list = baseUserGroupService.selectBaseUserGroupList(baseUserGroup);
        return getDataTable(list);
    }

    /**
     * 导出用户分群列表
     */
    @PreAuthorize("@ss.hasPermi('base:group:export')")
    @Log(title = "用户分群", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(BaseUserGroupDO baseUserGroup)
    {
        List<BaseUserGroupDO> list = baseUserGroupService.selectBaseUserGroupList(baseUserGroup);
        ExcelUtil<BaseUserGroupDO> util = new ExcelUtil<BaseUserGroupDO>(BaseUserGroupDO.class);
        return util.exportExcel(list, "group");
    }

    @GetMapping("/exportUserDetail/{groupId}")
    public AjaxResult exportUserDetail(@PathVariable("groupId") Integer groupId)
    {
        SysUser currentUser= SecurityUtils.getLoginUser().getUser();
        String lesseeId = currentUser.getLesseeId();

        BaseUserGroupDO group=baseUserGroupService.selectBaseUserGroupById(groupId);
        Map<String,Object> param = new HashMap<>();
        param.put("tableId",group.getName());
        param.put("lesseeId",lesseeId);
        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_users,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        List list = new ArrayList();
        List<UserDetailVo> detailList = new ArrayList();

        JSONObject dataObj = obj.getJSONObject("data");
        int total = 0;
        if (Objects.nonNull(dataObj) && dataObj.containsKey("total") && dataObj.containsKey("rows")){
            total = dataObj.getInteger("total");
            list = dataObj.getJSONArray("rows");
            for(int i=0;i<list.size();i++){
                UserDetailVo vo=JSONObject.parseObject(list.get(i).toString(),UserDetailVo.class);
                detailList.add(vo);
            }
        }
        ExcelUtil<UserDetailVo> util = new ExcelUtil<UserDetailVo>(UserDetailVo.class);
        return util.exportExcel(detailList, "group");
    }

    /**
     * 获取用户分群详细信息
     */
    @PreAuthorize("@ss.hasPermi('base:group:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Integer id)
    {
        return AjaxResult.success(baseUserGroupService.selectBaseUserGroupById(id));
    }

    @GetMapping(value = "/queryEventProperty/{id}")
    public AjaxResult queryEventProperty(@PathVariable("id") String id)
    {
        List result=new ArrayList();
        Map m1=new HashMap();
        m1.put("eventItemName","是否首日访问");
        m1.put("eventItemValue","是");
        result.add(m1);

        Map m2=new HashMap();
        m2.put("eventItemName","最近一次站外地址");
        m2.put("eventItemValue","广州市");
        result.add(m2);

        Map m3=new HashMap();
        m3.put("eventItemName","元素名字");
        m3.put("eventItemValue","button");
        result.add(m3);

        Map m4=new HashMap();
        m4.put("eventItemName","ID");
        m4.put("eventItemValue",id);
        result.add(m4);
        return AjaxResult.success(result);
    }

    @GetMapping(value = "/queryEventPropertys")
    public AjaxResult queryEventPropertys(@RequestParam(value="distinctId",required = false) String distinctId,
                                          @RequestParam(value="eventType",required = false) String eventType,
                                          @RequestParam(value="time",required = false) String time)
    {
        EventItemDO itemParam = new EventItemDO();
        itemParam.setEventType(eventType);
        itemParam.setStatus("Y");
        List<EventItemDO> itemList = eventItemService.selectEventItemByType(itemParam);
        if (itemList.isEmpty()){
            return AjaxResult.success(new ArrayList<>());
        }

        Map<String,Object> param = new HashMap<>();

        param.put("distinctId",distinctId);
        param.put("eventType",eventType);
        param.put("time",time);
        List<Map<String,Object>> itemMapList = new ArrayList<>();
        for (EventItemDO itemDO : itemList){
            Map<String,Object> map = new HashMap<>();
            map.put("eventItemCode",itemDO.getEventItemCode());
            map.put("eventItemName",itemDO.getEventItemName());
            itemMapList.add(map);
        }
        param.put("itemList",itemMapList);

        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_user_event_item,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        JSONArray array = obj.getJSONArray("data");
//        List result=new ArrayList();


        return AjaxResult.success(array);

    }

    @GetMapping(value = "/history/{id}")
    public AjaxResult getGroupHistroyInfo(@PathVariable("id") Long id)
    {
        BaseUserGroupTaskDetail detail=new BaseUserGroupTaskDetail();
        detail.setGroupId(id);
        List<BaseUserGroupTaskDetail> detailList=baseUserGroupTaskDetailService.selectBaseUserGroupTaskDetailList(detail);
        Map<String,Object> resultMap=new HashMap();
        List title=new ArrayList();
        List<Integer> chartData=new ArrayList<>();
        detailList.stream().forEach(taskDetail->{
            title.add(taskDetail.getBatchNo());
            chartData.add(taskDetail.getResultNum());
        });

        Map<String,Object> dataMap1=new HashMap();
        dataMap1.put("name","分群统计结果");
        dataMap1.put("type","bar");
        dataMap1.put("data",chartData);

        resultMap.put("tableData",detailList);
        resultMap.put("chartData",dataMap1);
        resultMap.put("chartTitle",title);
        return AjaxResult.success(resultMap);
    }



    /**
     * 新增用户分群
     */
    @PreAuthorize("@ss.hasPermi('base:group:add')")
    @Log(title = "用户分群", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BaseUserGroupDO baseUserGroup)
    {
        return toAjax(baseUserGroupService.insertBaseUserGroup(baseUserGroup));
    }

    /**
     * 修改用户分群
     */
    @PreAuthorize("@ss.hasPermi('base:group:edit')")
    @Log(title = "用户分群", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BaseUserGroupDO baseUserGroup)
    {
        return toAjax(baseUserGroupService.updateBaseUserGroup(baseUserGroup));
    }

    /**
     * 删除用户分群
     */
    @PreAuthorize("@ss.hasPermi('base:group:remove')")
    @Log(title = "用户分群", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Integer[] ids)
    {
        return toAjax(baseUserGroupService.deleteBaseUserGroupByIds(ids));
    }


    @GetMapping("/userDetailList")
    public TableDataInfo userDetailList(BaseUserGroupDO baseUserGroup)
    {
        SysUser currentUser= SecurityUtils.getLoginUser().getUser();
        String lesseeId = currentUser.getLesseeId();

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Map<String,Object> param = new HashMap<>();
        param.put("current",pageDomain.getPageNum());
        param.put("pageSize",pageDomain.getPageSize());
        param.put("tableId",baseUserGroup.getName());
        param.put("lesseeId",lesseeId);
        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_users,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        List list = new ArrayList();

        JSONObject dataObj = obj.getJSONObject("data");
        int total = 0;
        if (Objects.nonNull(dataObj) && dataObj.containsKey("total") && dataObj.containsKey("rows")){
            total = dataObj.getInteger("total");
            list = dataObj.getJSONArray("rows");
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(total);
        log.info("userDetailList:"+ JSONUtil.toJsonStr(rspData));

        return rspData;
    }

    @GetMapping(value = "/user/info/{id}")
    public AjaxResult getUserInfo(@PathVariable("id") String id)
    {
        Map<String,Object> param = new HashMap<>();
        param.put("distinctId",id);

        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_user_info,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }

        JSONObject dataObj = obj.getJSONObject("data");

        return AjaxResult.success(dataObj);
    }

    @GetMapping(value = "/user/pathExample")
    public AjaxResult getUserPathInfoExample(@RequestParam(value="id",required = true) String id,
                                      @RequestParam(value="beginDate",required = false) Date beginDate,
                                      @RequestParam(value="endDate",required = false) Date endDate,
                                      @RequestParam(value="sortType",required = false) String sortType)
    {
        Map<String,Object> param = new HashMap<>();
        param.put("distinctId",id);

        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_user_info,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }

        JSONObject dataObj = obj.getJSONObject("data");

        List resultList=new ArrayList();

        Map result1=new HashMap();
        result1.put("timestamp","2022-01-18");

        List children=new ArrayList();
        Map child1=new HashMap();
        child1.put("timevalue","23:12:10");
        child1.put("eventType","小程序首次启动");

        List itemList=new ArrayList();
        Map item1=new HashMap();
        item1.put("itemName","$是否首次启动");
        item1.put("itemValue","假");
        itemList.add(item1);

        Map item2=new HashMap();
        item2.put("itemName","页面参数");
        item2.put("itemValue","linkId=https://www.sensorsdata.cn");
        itemList.add(item2);
        child1.put("itemList",itemList);
        children.add(child1);

        Map child2=new HashMap();
        child2.put("timevalue","19:08:10");
        child2.put("eventType","App 崩溃");
        child2.put("itemList",new ArrayList<>());
        children.add(child2);

        result1.put("eventList",children);

        resultList.add(result1);

        Map result2=new HashMap();
        result2.put("timestamp","2022-01-16");

        List children2=new ArrayList();
        Map child21=new HashMap();
        child21.put("timevalue","23:12:10");
        child21.put("eventType","小程序首次启动");

        List itemList2=new ArrayList();
        Map item21=new HashMap();
        item21.put("itemName","$是否首次启动");
        item21.put("itemValue","假");
        itemList2.add(item21);

        Map item22=new HashMap();
        item22.put("itemName","页面参数");
        item22.put("itemValue","linkId=https://www.sensorsdata.cn");
        itemList2.add(item22);
        child21.put("itemList",itemList);
        children2.add(child21);

        Map child22=new HashMap();
        child22.put("timevalue","19:08:10");
        child22.put("eventType","App 崩溃");
        child22.put("itemList",itemList);
        children2.add(child22);

        result2.put("eventList",children2);

        resultList.add(result2);


        return AjaxResult.success(resultList);
    }

    @GetMapping(value = "/user/path")
    public AjaxResult getUserPathInfo(@RequestParam(value="id",required = true) String id,
                                             @RequestParam(value="beginDate",required = false) String beginDate,
                                             @RequestParam(value="endDate",required = false) String endDate,
                                             @RequestParam(value="sortType",required = false) String sortType)
    {
        List<UserTrackGroupVO> resList = new ArrayList<>();
        if (StringUtils.isEmpty(beginDate) || "undefined".equals(beginDate)){
            beginDate = "";
            endDate = "";
        }
        Map<String,Object> param = new HashMap<>();
        String startDate = "";
        String tempEndDate = "";
//        if (StringUtils.isEmpty(beginDate)){
//            startDate = DateUtils.getYYYYMMDD(-6);
//            tempEndDate = DateUtils.getYYYYMMDD(-1);
//        }else{
//            startDate = beginDate.length()>10?beginDate.substring(0,10):beginDate;
//            tempEndDate = endDate.length()>10?endDate.substring(0,10):endDate;
//        }
        param.put("distinctId",id);
        param.put("startDate",startDate);
        param.put("endDate",tempEndDate);
        param.put("sort",sortType);

        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_user_track_group,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        List<EventTypeDO> eventTypeList = eventTypeService.selectEventTypeList(new EventTypeDO());

        JSONArray array = obj.getJSONArray("data");
        if (!array.isEmpty()){
            resList = JSONArray.parseArray(array.toJSONString(),UserTrackGroupVO.class);
            resList.stream().forEach(a -> {
                List<UserTrackVO> trackList = a.getTrackList();
                for (UserTrackVO vo : trackList){
                    vo.setEventTypeName(getEventName(vo.getEventType(),eventTypeList));
                }
            });
        }

        return AjaxResult.success(resList);
    }


    @PreAuthorize("@ss.hasPermi('base:group:add')")
    @Log(title = "添加用户分群", businessType = BusinessType.INSERT)
    @PostMapping("/createUserGroup")
    public AjaxResult createUserGroup(@RequestBody String requestJson)throws Exception{
        logger.info(requestJson);
        JSONObject jsonObj=JSONObject.parseObject(requestJson);
        JSONObject object=jsonObj.getJSONObject("requestJson");
        BaseUserGroupDO groupdo=JSONObject.parseObject(object.toJSONString(),BaseUserGroupDO.class);
        String tableName= SqlTableUtil.getGroupName();
        groupdo.setName(tableName);
        groupdo.setGroupRule(object.toJSONString());
        object.put("tableId",groupdo.getName());
        object.put("tableType","ADD");
        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.create_users,object);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        Long num= Convert.toLong(obj.getString("data"));
        groupdo.setResultTime(DateUtils.getNowDate());
        groupdo.setResultNum(num);
        groupdo.setUpdateTime(DateUtils.getNowDate());
        baseUserGroupService.insertBaseUserGroup(groupdo);
        addTaskDetail(groupdo,num);
        String executorParam="url: "+thirdProperties.getLocalUrl()+ThirdInterface.groupXxJobTask+"/"+groupdo.getName()+"\n" +
                "method: get";
        JSONObject requestInfo = new JSONObject();
        requestInfo.put("jobGroup",1);
        requestInfo.put("scheduleType","CRON");
        requestInfo.put("jobDesc",groupdo.getDisplayName());
        requestInfo.put("executorRouteStrategy","FIRST");
        requestInfo.put("scheduleConf","31 0 0 * * ?");
        requestInfo.put("misfireStrategy","FIRE_ONCE_NOW");
        requestInfo.put("glueType","BEAN");
        requestInfo.put("executorHandler","httpUserGroupJobHandler");
        requestInfo.put("executorBlockStrategy","SERIAL_EXECUTION");
        requestInfo.put("executorTimeout",5);
        requestInfo.put("executorFailRetryCount",1);
        requestInfo.put("author","admin");
        requestInfo.put("alarmEmail","229049640@qq.com");
        requestInfo.put("executorParam",executorParam);
        requestInfo.put("glueRemark",groupdo.getDisplayName()+"定时任务");
        JSONObject response= WebUtils.postCkObj(thirdProperties.getXxjobUrl(),ThirdInterface.createJobInfo,requestInfo);
        if(response.containsKey("code")&&200==response.getIntValue("code")){
            return AjaxResult.success();
        }else{
            return AjaxResult.error("调用api接口失败！");
        }
    }

    @Log(title = "预估用户分群数量", businessType = BusinessType.OTHER)
    @PostMapping("/calcUserGroupNumber")
    public AjaxResult calcUserGroupNumber(@RequestBody String requestJson){
        logger.info(requestJson);
        logger.info(thirdProperties.getCkUrl());
        JSONObject jsonObj=JSONObject.parseObject(requestJson);
        Map<String, Object> object=jsonObj.getJSONObject("requestJson");
        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_count,object);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        return AjaxResult.success(Convert.toInt(obj.getString("data")));
    }

    @GetMapping(value = "/userGroupXxjobTask/{name}")
    public AjaxResult userGroupXxjobTask(@PathVariable("name") String name)
    {
        log.info("分群["+name+"]调度任务开始执行");
        BaseUserGroupDO group=new BaseUserGroupDO();
        group.setName(name);
        List<BaseUserGroupDO> groupList=baseUserGroupService.selectBaseUserGroupList(group);
        if(groupList.size()==1){
            group=groupList.get(0);
            JSONObject param = JSONObject.parseObject(group.getGroupRule());
//            JSONObject object=(JSONObject)JSONObject.toJSON(group);
            param.put("tableId",group.getName());
            param.put("tableType","Task");
//            object.put("groupRule",group.getGroupRule());
            JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.create_users,param);
            if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
                AjaxResult.error(obj.getString("msg"));
            }
            Long num= Convert.toLong(obj.getString("data"));
            group.setResultNum(num);
            group.setStatus("01");
            group.setResultTime(DateUtils.getNowDate());
            group.setUpdateTime(DateUtils.getNowDate());
            baseUserGroupService.updateBaseUserGroup(group);
            addTaskDetail(group, num);
        }
        else{
            AjaxResult.error("分群ID["+name+"]查询数据错误");
        }
        return AjaxResult.success(null);
    }

    private void addTaskDetail(BaseUserGroupDO group, Long num) {
        //新添加一条执行记录
        BaseUserGroupTaskDetail detail=new BaseUserGroupTaskDetail();
        detail.setBatchNo(DateUtils.dateTime());
        detail.setGroupId(Long.valueOf(group.getId()+""));
        detail.setGroupCode(group.getName());
        detail.setGroupName(group.getDisplayName());
        detail.setTaskTime(DateUtils.getNowDate());
        detail.setResultNum(num !=null? num.intValue():0);
        detail.setResultTime(DateUtils.getNowDate());
        detail.setTaskStatus("01");
        baseUserGroupTaskDetailService.insertBaseUserGroupTaskDetail(detail);
    }

    private String getEventName(String code,List<EventTypeDO> eventTypeList){
        Optional<EventTypeDO> optional = eventTypeList.stream().filter(property -> property.getEventType().equals(code)).findFirst();
        if (optional.isPresent()) {
            // 存在
            EventTypeDO org =  optional.get();
            return org.getEventTypeName();
        } else {
            // 不存在
        }
        return code;
    }
}
